"""
@breif 修改运行时参数的简单框架
@description
    将修改程序参数的逻辑简单实现为框架，作为底层模块，通过接口与其他模块配合、提供功能，
    以提高复用性。
    
    ## 基本思路
    首先，对任务侧，要将可被修改调整的``Parameters``变量注册进本模块，并同时给出用来寻找
    这个变量的名称; 对用户侧(客户端)，提供几个接口函数，外部模块通过向接口函数传入名称(和对应的
    值)来查看/修改的相应的参数。
    
    采用单例模式，即把模块本身当作对象实例，利用Python模块只导入一次的特性实现单例。
    
    # 名称层级(两层)
    第一层是 Parameter 变量, 第二层是具体的键值对.
    {
    name:
        {key: value, key: value, ...},
    name:
        {key: value, key: value, ...},
        ...        
    }
@author Stone at BlueNet, GDOU
@date Nov.2020
"""
from parameter import Parameters
from copy import deepcopy

# from parameter import Parameters


# 集中将被管理的, 意图由用户修改的运行时参数
runtime_params = dict()  # format: 'name': Parameters


# ===== ===== ===== ===== ===== =====
# 任务侧注册运行时参数的接口
# ===== ===== ===== ===== ===== =====
def register_params(name, params):
    """
    注册可被其他模块修改的运行时参数, 以便于control_proxy管理.
    :param name: <str> 用于索引运行时参数对象的名称
    :param params: <Parameters> 对象
    """
    # TODO check the interface
    runtime_params[name] = params


# ===== ===== ===== ===== ===== =====
# 用户侧读/写运行时参数的接口
# ===== ===== ===== ===== ===== =====
def get_params(name):
    """根据 name 获取参数的键值对, 若找不到则返回None.
    :param name: 参数组的名称(使用register_params注册时所用的名称)
    :returns: dict, or None
    """
    try:
        return deepcopy(runtime_params[name]._params)
    except KeyError:
        return None


def get_value(name, key):
    """根据 name 和 key 直接获得键值对的值, 若找不到则返回None"""
    try:
        params = runtime_params[name]
        value = params[key]
        
        return value
        
    except KeyError:
        return None


def update_params(name, params_dict):
    """整个地修改参数组中的键值对, 成功修改返回True, 否则(找不到该name等)则返回False"""
    try:
        params = runtime_params[name]
        params._update(params_dict)
        
        return True
        
    except KeyError:
        return False


def set_value(name, key, value):
    """通过 name 和 key 直接修改某一个键值对的值. 若成功, 返回 True, 否
    则(找不到该键值对等)返回None"""
    try:
        params = runtime_params[name]
        params._update({key: value})
        
        return True
    
    except KeyError:
        return False
    




